<?php

namespace Leantime\Domain\Users\Controllers {

    use Leantime\Core\Controller\Controller;
    use Leantime\Core\Controller\Frontcontroller as FrontcontrollerCore;
    use Leantime\Core\UI\Theme as ThemeCore;
    use Leantime\Domain\Setting\Services\Setting as SettingService;
    use Leantime\Domain\Users\Repositories\Users as UserRepository;
    use Leantime\Domain\Users\Services\Users as UserService;
    use Symfony\Component\HttpFoundation\Response;

    class EditOwn extends Controller
    {
        private ThemeCore $themeCore;

        private UserRepository $userRepo;

        private SettingService $settingsService;

        private UserService $userService;

        private int $userId;

        /**
         * init - initialize private variables
         */
        public function init(
            ThemeCore $themeCore,
            UserRepository $userRepo,
            SettingService $settingsService,
            UserService $userService
        ): void {
            $this->themeCore = $themeCore;
            $this->userRepo = $userRepo;
            $this->settingsService = $settingsService;
            $this->userService = $userService;

            $this->userId = session('userdata.id');
        }

        /**
         * @throws \Exception
         */
        public function get(): Response
        {

            $row = $this->userRepo->getUser($this->userId);

            $userLang = $this->settingsService->getSetting('usersettings.'.$this->userId.'.language');

            if (! $userLang) {
                $userLang = $this->language->getCurrentLanguage();
            }

            $userTheme = $this->settingsService->getSetting('usersettings.'.$this->userId.'.theme');
            if (! $userTheme) {
                $userTheme = 'default';
            }

            $userColorMode = $this->settingsService->getSetting('usersettings.'.$this->userId.'.colorMode');
            if (! $userColorMode) {
                $userColorMode = 'light';
            }

            $availableColorSchemes = $this->themeCore->getAvailableColorSchemes();
            $userColorScheme = $this->settingsService->getSetting('usersettings.'.$this->userId.'.colorScheme');
            if (! $userColorScheme) {
                $userColorScheme = isset($availableColorSchemes['companyColors']) ? 'companyColors' : 'themeDefault';
            }

            $themeFont = $this->settingsService->getSetting('usersettings.'.$this->userId.'.themeFont');
            if (! $themeFont) {
                $themeFont = 'Roboto';
            }

            $userDateFormat = $this->settingsService->getSetting('usersettings.'.$this->userId.'.date_format');
            $userTimeFormat = $this->settingsService->getSetting('usersettings.'.$this->userId.'.time_format');

            $timezone = $this->settingsService->getSetting('usersettings.'.$this->userId.'.timezone');

            if (! $timezone) {
                $timezone = date_default_timezone_get();
            }

            $timezonesAvailable = timezone_identifiers_list();

            // Build values array
            $values = [
                'firstname' => $row['firstname'],
                'lastname' => $row['lastname'],
                'user' => $row['username'],
                'phone' => $row['phone'],
                'role' => $row['role'],
                'jobTitle' => $row['jobTitle'],
                'jobLevel' => $row['jobLevel'],
                'department' => $row['department'],
                'notifications' => $row['notifications'],
                'twoFAEnabled' => $row['twoFAEnabled'],
                'messagesfrequency' => $this->settingsService->getSetting('usersettings.'.$row['id'].'.messageFrequency'),
            ];

            if (! $values['messagesfrequency']) {
                $values['messagesfrequency'] = $this->settingsService->getSetting('companysettings.messageFrequency');
            }

            $permitted_chars = '123456789abcdefghijklmnopqrstuvwxyz';
            session(['formTokenName' => substr(str_shuffle($permitted_chars), 0, 32)]);
            session(['formTokenValue' => substr(str_shuffle($permitted_chars), 0, 32)]);

            $this->tpl->assign('profilePic', $this->userRepo->getProfilePicture(session('userdata.id')));
            $this->tpl->assign('values', $values);

            $this->tpl->assign('userLang', $userLang);
            $this->tpl->assign('userTheme', $userTheme);
            $this->tpl->assign('themeFont', $themeFont);
            $this->tpl->assign('userColorMode', $userColorMode);
            $this->tpl->assign('userColorScheme', $userColorScheme);
            $this->tpl->assign('languageList', $this->language->getLanguageList());
            $this->tpl->assign('dateFormat', $userDateFormat);
            $this->tpl->assign('timeFormat', $userTimeFormat);
            $this->tpl->assign('dateTimeValues', $this->getSupportedDateTimeFormats());
            $this->tpl->assign('timezone', $timezone);
            $this->tpl->assign('availableColorSchemes', $availableColorSchemes);
            $this->tpl->assign('availableFonts', $this->themeCore->getAvailableFonts());
            $this->tpl->assign('availableThemes', $this->themeCore->getAll());
            $this->tpl->assign('timezoneOptions', $timezonesAvailable);

            $this->tpl->assign('user', $row);

            return $this->tpl->display('users.editOwn');
        }

        /**
         * @throws \Exception
         */
        public function post(): Response
        {

            // Save Profile Info
            $tab = '';

            if (isset($_POST[session('formTokenName')]) && session()->exists('formTokenName') && $_POST[session('formTokenName')] === session('formTokenValue')) {
                $row = $this->userRepo->getUser($this->userId);

                // profile Info
                if (isset($_POST['profileInfo'])) {
                    $tab = '#myProfile';

                    $values = [
                        'firstname' => ($_POST['firstname']) ?? $row['firstname'],
                        'lastname' => ($_POST['lastname']) ?? $row['lastname'],
                        'user' => ($_POST['user']) ?? $row['username'],
                        'phone' => ($_POST['phone']) ?? $row['phone'],
                        'notifications' => $row['notifications'],
                        'twoFAEnabled' => $row['twoFAEnabled'],
                    ];

                    $changedEmail = 0;
                    if ($row['username'] !== $values['user']) {
                        $changedEmail = 1;
                    }

                    // Validation
                    if ($values['user'] !== '') {
                        if (filter_var($values['user'], FILTER_VALIDATE_EMAIL)) {
                            if ($changedEmail === 1) {
                                if ($this->userRepo->usernameExist($values['user'], $this->userId) === false) {
                                    $this->userService->editOwn($values, $this->userId);
                                    $this->tpl->setNotification($this->language->__('notifications.profile_edited'), 'success', 'profile_edited');
                                } else {
                                    $this->tpl->setNotification($this->language->__('notification.user_exists'), 'error');
                                }
                            } else {
                                $this->userService->editOwn($values, $this->userId);
                                $this->tpl->setNotification($this->language->__('notifications.profile_edited'), 'success', 'profile_edited');
                            }
                        } else {
                            $this->tpl->setNotification($this->language->__('notification.no_valid_email'), 'error');
                        }
                    } else {
                        $this->tpl->setNotification($this->language->__('notification.enter_email'), 'error');
                    }
                }

                // Save Password
                if (isset($_POST['savepw'])) {
                    $tab = '#security';

                    $values = [
                        'firstname' => $row['firstname'],
                        'lastname' => $row['lastname'],
                        'user' => $row['username'],
                        'phone' => $row['phone'],
                        'password' => $row['password'],
                        'notifications' => $row['notifications'],
                        'twoFAEnabled' => $row['twoFAEnabled'],
                    ];

                    if (password_verify($_POST['currentPassword'], $values['password'])) {

                        if ($_POST['newPassword'] === $_POST['confirmPassword']) {
                            if ($this->userService->checkPasswordStrength($_POST['newPassword'])) {
                                $values['password'] = $_POST['newPassword'];
                                $this->userRepo->editOwn($values, $this->userId);
                                $this->tpl->setNotification(
                                    $this->language->__('notifications.password_changed'),
                                    'success',
                                    'password_edited'
                                );
                            } else {
                                $this->tpl->setNotification(
                                    $this->language->__('notification.password_not_strong_enough'),
                                    'error'
                                );
                            }
                        } else {
                            $this->tpl->setNotification(
                                $this->language->__('notification.passwords_dont_match'),
                                'error'
                            );
                        }
                    } else {
                        $this->tpl->setNotification(
                            $this->language->__('notification.previous_password_incorrect'),
                            'error'
                        );
                    }
                }

                if (isset($_POST['saveTheme'])) {
                    $tab = '#theme';

                    $postTheme = htmlentities($_POST['theme'] ?? 'default');
                    $postColorMode = htmlentities($_POST['colormode'] ?? 'light');
                    $postColorScheme = htmlentities($_POST['colorscheme'] ?? 'themeDefault');
                    $themeFont = htmlentities($_POST['themeFont']);

                    $this->settingsService->saveSetting('usersettings.'.$this->userId.'.theme', $postTheme);
                    $this->settingsService->saveSetting('usersettings.'.$this->userId.'.colorMode', $postColorMode);
                    $this->settingsService->saveSetting('usersettings.'.$this->userId.'.colorScheme', $postColorScheme);
                    $this->settingsService->saveSetting('usersettings.'.$this->userId.'.themeFont', $themeFont);
                    $this->themeCore::clearCache();
                    $this->themeCore->setActive($postTheme);
                    $this->themeCore->setColorMode($postColorMode);
                    $this->themeCore->setColorScheme($postColorScheme);
                    $this->themeCore->setFont($themeFont);
                    $this->themeCore::clearCache();

                    $this->tpl->setNotification($this->language->__('notifications.changed_profile_settings_successfully'), 'success', 'themsettings_updated');
                }

                // Save Look & Feel
                if (isset($_POST['saveSettings'])) {
                    $tab = '#settings';

                    $postLang = htmlentities($_POST['language']);

                    $dateFormat = htmlentities($_POST['date_format']);
                    $timeFormat = htmlentities($_POST['time_format']);
                    $tz = htmlentities($_POST['timezone']);

                    $this->settingsService->saveSetting('usersettings.'.$this->userId.'.language', $postLang);
                    $this->settingsService->saveSetting('usersettings.'.$this->userId.'.date_format', $dateFormat);
                    $this->settingsService->saveSetting('usersettings.'.$this->userId.'.time_format', $timeFormat);
                    $this->settingsService->saveSetting('usersettings.'.$this->userId.'.timezone', $tz);

                    session()->forget('cache.language_resources_'.$this->language->getCurrentLanguage());

                    session(['usersettings.date_format' => $dateFormat]);
                    session(['usersettings.time_format' => $timeFormat]);
                    session(['usersettings.timezone' => $tz]);

                    $this->language->setLanguage($postLang);

                    $this->tpl->setNotification($this->language->__('notifications.changed_profile_settings_successfully'), 'success', 'profilesettings_updated');
                }

                // Save Profile Image
                if (isset($_POST['profileImage'])) {
                    $tab = '#myProfile';
                }

                // Save Notifications
                if (isset($_POST['savenotifications'])) {
                    $tab = '#notifications';

                    $values = [
                        'firstname' => $row['firstname'],
                        'lastname' => $row['lastname'],
                        'user' => $row['username'],
                        'phone' => $row['phone'],
                        'notifications' => $row['notifications'],
                        'twoFAEnabled' => $row['twoFAEnabled'],
                    ];

                    if (isset($_POST['notifications'])) {
                        $values['notifications'] = 1;
                    } else {
                        $values['notifications'] = 0;
                    }

                    $this->userRepo->editOwn($values, $this->userId);

                    // Storing option messagefrequency
                    $this->settingsService->saveSetting('usersettings.'.$this->userId.'.messageFrequency', (int) ($_POST['messagesfrequency'] ?? 3600));

                    $this->tpl->setNotification($this->language->__('notifications.changed_profile_settings_successfully'), 'success', 'profilesettings_updated');
                }
            } else {
                $this->tpl->setNotification($this->language->__('notification.form_token_incorrect'), 'error');
            }

            // Redirect
            return FrontcontrollerCore::redirect(BASE_URL.'/users/editOwn'.$tab);
        }

        /**
         * Returns list of supported varying date-time formats.
         *
         * @link https://www.php.net/manual/en/class.datetimeinterface.php#datetimeinterface.constants.types
         *
         * @return array<string> Format of ID => date-time string
         */
        private function getSupportedDateTimeFormats(): array
        {
            return [
                'dates' => [
                    $this->language->__('language.dateformat'),
                    'Y-m-d',
                    'D, d M y',
                    'l, d-M-y',
                    'd.m.Y',
                    'd/m/Y',
                    'd. F Y',
                    'm-d-Y',
                    'dmY',
                    'F d, Y',
                    'd F Y',
                ],
                'times' => [
                    $this->language->__('language.timeformat'),
                    'H:i P',
                    'H:i O',
                    'H:i T',
                    'H:i:s',
                    'H:i',
                ],
            ];
        }
    }
}
